<template>
    <div id="content">
        <div class="imgBox" v-if="imgurl" ref="imgBox">
            <img :src="imgurl" alt="" ref="imgRef" @load="onImageLoad" />
            <!-- <div class="eigItem" v-for="item in sensor_eig" v-show="eig_show" :key="item" :style="`left:${item.graphArr[0] * 100 + '%'};top:${item.graphArr[1] * 100 + '%'}`" :class="`d${item.id}`"></div> -->
        </div>
        <div class="img25d_noData" v-else>
            <img src="@/assets/DeviceDetails/noData.png" alt />
            <div>暂无数据</div>
        </div>
        <div class="canvasBox" ref="canvasBox"></div>
        <el-dialog title="设置图片" :visible.sync="isShow" width="40%" @closed="handClosed">
            <el-form ref="form" :model="form" label-width="80px">
                <el-form-item label="设备图片:">
                    <el-upload :action="action" list-type="picture-card" :headers="headers" :on-preview="handlePreview" accept=".jpg,.png,.bmp" :on-success="handSuccess" :file-list="fileList" limit="1">
                        <i class="el-icon-plus"></i>
                    </el-upload>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="Submit">提交</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
        <recent-eig ref="recentEig1" :sensorInfo="sensorSelected"></recent-eig>
    </div>
</template>
<script>
import { deviceGetDevice25dApi, deviceSaveGraphApi, deviceUpload25Dapi } from '@/requset/api'
import { requestApi } from '@/requset/api'
import { Graph, Shape } from '@antv/x6'
import { mapState } from 'vuex'
import recentEig from '@/components/recentEig'
import { warn_color, desArrs, tagsArrs } from './config'

export default {
    data() {
        return {
            isShow: false,
            device_name: '',
            device_id: null,
            headers: {
                Authorization: '',
            },
            fileList: [{ url: '' }],
            action: '/api/report/upload',
            static_url: '/static',
            imgurl: '',
            sensor: [],
            sensor_eig: [],
            eig_show: [],
            graph: null,
            graphObj: [],
            warn_color: [],
            desArrs: {},
            tagsArrs: {},
            form: {
                device_25D_img: '',
            },
            sensorSelected: {},
            rects: [],
            clients: [],
            operate: 2,
            refreshtime: 12000,
            timers: [],
            eig_times: {},
        }
    },
    props: ['iskeep', 'active'],
    computed: {
        ...mapState('backstage', ['mqttConfig', 'sys_eig']),
    },
    components: { recentEig },
    methods: {
        //重绘图
        initImg(device_id) {
            this.clearGraph()
            this.device_id = device_id
            this.eig_times = {}

            this.deviceGetDevice25d(device_id)
        },
        onImageLoad() {
            console.log('图片加载完成')

            this.initImg(this.device_id)
            this.deviceGetDevice25d(this.device_id)
        },
        deviceGetDevice25d(id) {
            this.destroyMqttConnection()
            return deviceGetDevice25dApi(id).then((res) => {
                if (res.data.code == 0) {
                    this.$nextTick(() => {
                        this.device_name = res.data.data[0].device_name
                        this.imgurl = res.data.data[0].imgurl
                        this.sensor = res.data.data[0].sensor
                        this.timers.forEach((e) => {
                            clearInterval(e)
                            e = null
                        })
                        this.timers = []
                        this.rects = []
                        setTimeout(() => {
                            this.sensor.forEach((e, i) => {
                                if (e.graph) {
                                    e.graphArr = JSON.parse(e.graph)
                                }
                                if (this.imgurl) {
                                    if (!this.graph)
                                        this.initGraph().then(() => {
                                            this.addNode(e, this.graph, i)
                                        })
                                    else {
                                        this.addNode(e, this.graph, i)
                                    }
                                }
                            })
                        }, 200)
                    })
                }
            })
        },
        setDiv(arr) {
            let str = ' '
            arr.forEach((e, i) => {
                if (i <= 1) {
                    str = str + `<div class="eig_item eig_item_title">${e}</div>`
                } else str = str + `<div class="eig_item">${e}</div>`
            })
            return str
        },
        getMqtt(e, i) {
            let { address, port, topic, direction, group_id } = e
            if (topic && topic != '') {
                topic += `${port}/${address}`
            }
            console.log('e', e)
            requestApi('post', 'eigenvalue/sql/data', { id: e.sensor_id }, false).then((res) => {
                let realTimeData = {}
                if (res.data.data.length === 0) {
                    return
                } else {
                    let data = res.data.data[0].data
                    for (let key in data) {
                        if (['X', 'Y', 'Z'].includes(key)) {
                            for (let k in data[key]) {
                                realTimeData[k + '_' + key] = data[key][k]
                            }
                        } else {
                            realTimeData[key] = data[key]
                        }
                    }
                    if (group_id == 1582) {
                        let time = this.dayjs().format('YYYY-MM-DD HH:mm:ss')
                        const randomNumber = Math.random()
                        const tem = parseFloat((randomNumber * 1 + 37).toFixed(1))
                        const vel = parseFloat((randomNumber + 1).toFixed(1))
                        const acc = parseFloat((randomNumber + 2).toFixed(1))
                        this.rects[i].attr('label/text', time + '\n' + e.sensor_name + '\n' + `${vel}mm/s  ${acc}m/s² ${tem}℃`)
                        let label = this.rects[i].attr('label').text
                        let ctx = document.createElement('canvas').getContext('2d')
                        ctx.font = '14px sans-serif'
                        const lines = label.split('\n')
                        let maxWidth = 0
                        lines.forEach((line) => {
                            const width = ctx.measureText(line).width
                            if (width > maxWidth) {
                                maxWidth = width
                            }
                        })
                        const measuredWidth = maxWidth + 10
                        this.rects[i].size(measuredWidth, 48)
                        this.changeGCData({ vel, acc, tem })
                        return
                    }
                    let aresult = realTimeData
                    let list = e.sys_eig.split(',').map((item) => Number(item))
                    let tags = []
                    this.sys_eig.forEach((item) => {
                        if (list.includes(item.id)) {
                            if (item.vibration === 3) {
                                let ll = e.address.includes('_') ? ['Z'] : ['X', 'Y', 'Z']
                                ll.forEach((d) => {
                                    tags.push({
                                        name: e.address.includes('_') ? item.name : d + '轴' + item.name,
                                        nickname: item.nickname + '_' + d,
                                        unit: item.unit,
                                        id: item.id,
                                    })
                                })
                            } else {
                                tags.push(item)
                            }
                        }
                    })
                    if (this.sys_eig[0].sort) {
                        tags.sort((a, b) => this.sys_eig.find((item) => item.id === a.id).sort - this.sys_eig.find((item) => item.id === b.id).sort)
                    }

                    let classs = '.custom-html' + 'des' + e.sensor_id
                    let asss = document.querySelector(classs)
                    let time = this.dayjs(res.data.data[0]._id.split('_')[3] * 1000).format('YYYY-MM-DD HH:mm:ss')

                    asss.innerHTML = this.setDiv([
                        time,
                        e.sensor_name,
                        ...tags.filter((e) => aresult[e.nickname] !== undefined).map((item) => `<span>${item.name} </span><span>${aresult[item.nickname]}${item.unit}</span>`),
                    ])

                    this.eig_times['time' + i] = time
                }
            })
        },
        changeGCData(e) {
            this.$emit('changeGCData', e)
        },
        destroyMqttConnection() {
            console.log('断开连接 清除定时器')
            this.timers.forEach((e) => {
                clearInterval(e)
                e = null
            })
            this.timers = []
            if (this.clients.length != 0) {
                this.clients.forEach((e) => {
                    if (e.client) {
                        e.client.unsubscribe(e.topic)
                    }
                })
                this.clients = []

                this.rects = []
            }
        },
        // 根据主轴筛选特征值标签
        getSpindle(inputObject, dir) {
            this.getResult()
            if (!inputObject) {
                return {}
            }
            let properties = []
            this.sys_eig.forEach((item) => {
                if (item.vibration === 3) {
                    let newItem1 = { ...item, nickname: item.nickname + '_x' }
                    let newItem2 = { ...item, nickname: item.nickname + '_y' }
                    let newItem3 = { ...item, nickname: item.nickname + '_z' }
                    properties.push(newItem1, newItem2, newItem3)
                } else {
                    properties.push(item)
                }
            })
            const filteredObject = Object.keys(inputObject)
                .filter((key) => {
                    const property = properties.find((prop) => prop.nickname == key)
                    return property && (key == 'vel_rms_z' || key == 'acc_rms_z' || key === 'tem')
                })
                .reduce((obj, key) => {
                    const value = inputObject[key]
                    const property = properties.find((prop) => prop.nickname === key)
                    obj[key] = value + property.unit
                    return obj
                }, {})

            return filteredObject
        },
        getResult(a, b) {
            const result = []
            for (const [key, value] of Object.entries(a)) {
                for (const item of b) {
                    if (key.includes(item.nickname)) {
                        let { vibration, unit, name } = item
                        if (vibration == 3) {
                            if (key.endsWith('z')) {
                                name = '垂直' + name
                            } else if (key.endsWith('x')) {
                                name = '水平' + name
                            } else if (key.endsWith('y')) {
                                name = '轴向' + name
                            }
                        }

                        let a = `<span>${name} </span><span>${value}${unit}</span>`
                        result.push(a)
                        break
                    }
                }
            }

            return result
        },
        handClosed() {
            this.fileList[0].url = null
        },
        addNode(obj, graph, i) {
            if (obj.sensor_name.includes('转速')) {
                return
            }
            this.$nextTick(() => {
                let canvasBox = this.$refs.canvasBox
                let width1 = canvasBox.clientWidth
                let height1 = canvasBox.clientHeight
                setTimeout(() => {
                    let imgRef = this.$refs.imgRef
                    let width2 = imgRef.clientWidth
                    let height2 = imgRef.clientHeight
                    var x1, y1, x2, y2
                    if (obj.graph) {
                        let arr = JSON.parse(obj.graph)
                        x1 = arr[0] * width1
                        y1 = arr[1] * height1
                        x2 = arr[2] * width2 + (width1 - width2) / 2
                        y2 = arr[3] * height2 + (height1 - height2) / 2
                    } else {
                        x1 = 0
                        y1 = 0
                        x2 = (width1 - width2) / 2
                        y2 = (height1 - height2) / 2
                    }

                    let id1 = 'des' + obj.sensor_id
                    let id2 = 'tag' + obj.sensor_id
                    Shape.HTML.register({
                        id: id1,
                        shape: 'custom-html' + id1,
                        width: 100,
                        effect: ['data'],
                        html(node) {
                            const div = document.createElement('div')
                            div.className = 'custom-html' + id1
                            div.innerHTML = `${node.attrs.content}`
                            return div
                        },
                    })

                    let rect = graph.addNode({
                        id: id1,
                        did: obj.sensor_id,
                        x: x1,
                        y: y1,
                        shape: 'custom-html' + id1,
                        zIndex: 99,
                        attrs: {
                            content: obj.sensor_name,
                        },
                    })

                    graph.addNode({
                        id: id2,
                        did: obj.sensor_id,
                        x: x2,
                        y: y2,
                        label: ' ',
                        shape: 'circle',
                        interactive: this.operate == 1,
                        attrs: {
                            body: {
                                fill: this.warn_color[obj.warn_level],
                                stroke: this.warn_color[obj.warn_level],
                                strokeWidth: 5,
                            },
                        },
                        width: 8,
                        height: 8,
                    })

                    // 绘线
                    graph.addEdge({
                        shape: 'edge',
                        source: {
                            cell: id1, // 源节点的 ID
                            anchor: { name: 'center' }, // 设置连接点在节点的中心
                        },
                        target: {
                            cell: id2, // 目标节点的 ID
                            anchor: { name: 'center' }, // 设置连接点在节点的中心
                        },
                        interactive: false,
                        attrs: {
                            line: {
                                targetMarker: false,
                                stroke: '#0CD9E8',
                                strokeWidth: 1,
                            },
                        },
                        router: {
                            name: 'orth',
                            args: {},
                        },
                        zIndex: 1,
                    })

                    this.getMqtt(obj, i)
                    // rect.timer = setInterval(() => {
                    //     this.getMqtt(obj, i)
                    // }, this.refreshtime)
                    let timer = setInterval(() => {
                        this.getMqtt(obj, i)
                    }, this.refreshtime)

                    this.timers.push(timer)
                    this.rects.push(rect)
                }, 100)
            })
        },
        // 清除画布上所有节点和线
        clearGraph() {
            if (this.graph) {
                let nodes = this.graph.getNodes()
                if (nodes.length != 0) {
                    this.graph.clearCells()
                }
            }
        },
        sensorClick(id, time) {
            this.$emit('img25dChangeData', id, time)
        },
        initGraph() {
            return new Promise((resolve) => {
                this.$nextTick(() => {
                    this.graph = new Graph({
                        container: this.$refs.canvasBox,
                        autoResize: true,
                    })
                    this.graph.on('node:moved', ({ e, x, y, node, view }) => {
                        this.graph.toJSON().cells.forEach((e) => {
                            if (e.id == node.id && e.shape != 'edge') {
                                e.position.x = node.position().x
                                e.position.y = node.position().y
                            }
                        })
                    })
                    this.graph.on('node:click', ({ e, x, y, node, view }) => {
                        let did = node.store.data.did
                        console.log('{ e, x, y, node, view }', { e, x, y, node, view })
                        let { feature_key } = node
                        console.log('feature_key', feature_key, node)
                        let a = this.sys_eig.find((e) => e.nickname == feature_key)
                        console.log('aaaa', a)
                        this.lableClick(did)
                    })
                    resolve()
                })
            })
        },
        saveGraph() {
            let sensor = []
            let canvasBox = document.querySelector('.canvasBox')
            let width = canvasBox.clientWidth
            let height = canvasBox.clientHeight
            let imgRef = this.$refs.imgRef
            let width2 = imgRef.clientWidth
            let height2 = imgRef.clientHeight

            this.sensor.forEach((e) => {
                let arr = []
                console.log('e', e.sensor_name, this.graph.toJSON().cells)
                this.graph.toJSON().cells.forEach((e1) => {
                    if (e.sensor_id == e1.did) {
                        if (e1.shape == 'circle') {
                            arr.push((e1.position.x - (width - width2) / 2) / width2)
                            arr.push((e1.position.y - (height - height2) / 2) / height2)
                        } else {
                            arr.push(e1.position.x / width)
                            arr.push(e1.position.y / height)
                        }
                    }
                })
                console.log('arr', arr)
                if (arr.length != 0) {
                    sensor.push({
                        id: e.sensor_id,
                        graph: JSON.stringify(arr),
                    })
                } else {
                    sensor.push({
                        id: e.sensor_id,
                        graph: '[0,0,0,0]',
                    })
                }
            })
            this.deviceSaveGraph({
                sensor,
            })
        },
        async deviceSaveGraph(obj) {
            let res = await deviceSaveGraphApi(obj)
            if (res.data.code == 0) {
                this.$message({
                    type: 'success',
                    message: '保存成功',
                })
            }
        },
        uploadImg() {
            if (this.imgurl && this.imgurl != '') {
                this.$set(this.fileList, 0, { url: this.imgurl })
            } else this.fileList.splice(0, 1)
            this.isShow = true
        },
        handSuccess(file) {
            if (file.code !== 0) {
                this.$message({
                    type: 'info',
                    message: '图片上传失败'.imgurl,
                })
                return
            }
            this.form.device_25D_img = file.data
        },
        Submit() {
            deviceUpload25Dapi({
                id: this.device_id,
                device_25D_img: this.form.device_25D_img,
            }).then((res) => {
                if (res.data.code == 0) {
                    this.$message({
                        type: 'success',
                        message: '上传成功',
                    })
                    this.isShow = false
                    this.deviceGetDevice25d(this.device_id)
                }
            })
        },
        lableClick(sensor_id) {
            this.$router.push(`/index/expdig/diagnosis?sensor_id=${sensor_id}&device_id=${this.device_id}`)
        },
        generateGUID() {
            function s4() {
                return Math.floor((1 + Math.random()) * 0x10000)
                    .toString(16)
                    .substring(1)
            }
            return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4()
        },
    },
    watch: {},
    created() {
        this.operate = sessionStorage.getItem('operate')
        let token = localStorage.getItem('token')
        this.headers.Authorization = token
        this.warn_color = warn_color
        this.desArrs = desArrs
        this.tagsArrs = tagsArrs
    },
    beforeDestroy() {
        this.destroyMqttConnection()
    },
}
</script>

<style lang="less" scoped>
#content {
    width: 100%;
    height: 100%;
    position: absolute;

    //
    .imgBox {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0%;
        top: 0%;
        display: flex;
        align-items: center;
        justify-content: center;

        img {
            display: block;
            height: 80%;
        }

        .description {
            position: absolute;
            padding: 2px 20px;
            width: 100px;
            line-height: 46px;
            height: 46px;
            color: #00ffff;
            font-weight: bold;
            background-image: url('@/assets/Home/menu_bg.png');
            background-size: 100% 100%;
            text-align: center;
            // background-color: red;
            z-index: 99;
        }
    }

    .canvasBox {
        width: 100%;
        height: 100%;

        position: absolute;
        z-index: 98;
    }
    .img25d_noData {
        width: 100%;
        height: 100%;
        text-align: center;
        top: 50%;
        position: absolute;
        left: 50%;
        transform: translate(-50%, -30%);

        img {
            width: 320px;
            // height: 100%;
        }

        div {
            color: #b2e3ff;
            font-weight: 600;
            font-size: 18px;
            text-align: center;
            margin-top: 16px;
        }
    }
}
</style>

<style lang="less">
[class^='custom-html'] {
    max-height: 132px;

    width: 200px;
    padding: 4px 2px;
    background-color: #036bd3;

    display: flex;
    align-items: center;
    padding: 0 10px;
    flex-direction: column;
    z-index: 99;
    overflow-y: auto;
    color: white;
    font-size: 16px;
    &::-webkit-scrollbar {
        width: 0; /* 隐藏水平滚动条 */
        height: 0; /* 隐藏垂直滚动条 */
    }
    .eig_item {
        width: 100%;
        line-height: 20px;
        text-align: left;
        display: flex;
        justify-content: space-between;
        margin-bottom: 2px;

        span {
            // width: 50%;
            text-align: center;
            display: flex;
            align-items: center;
            font-size: 14px;
        }

        background-color: #409eff;
        border-radius: 2px;
    }
    .eig_item_title {
        justify-content: center;
        background-color: #409eff;
        font-weight: bolder;
    }
}
</style>
